/**
 * 作者：
 * 创建时间：2012-6-27 上午11:35:28
 */
package dragon.model.fieldTemplate;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import dragon.core.exception.ExceptionHandler;
import dragon.core.io.FileHandler;
import dragon.core.util.FilePath;
import dragon.core.util.StringUtils;
import dragon.model.base.ModelSort;
import dragon.model.bizObject.BizObjectContainer;
import dragon.model.table.Table;

/**
 * 字段模板模型容器
 */
public class FieldTemplateContainer {

	/**
	 * 字段模板模型容器对象，用于存储系统中定义的所有字段模板模型对象<br>
	 * k:字段模板模型唯一标识符(code),v:FieldTemplate
	 */
	private static Map<String, FieldTemplate> container = new HashMap<String, FieldTemplate>();

	/**
	 * 加载全部字段模板模型
	 * 
	 * @throws ExceptionHandler
	 */
	public static void loadAll() throws ExceptionHandler {
		container.clear();// 先清空

		List<File> files = FileHandler.getFiles(FilePath.MODEL_FIELDTEMPLATE, 0, true);
		for (File file : files) {
			if (file.isDirectory()) {
				continue;
			}
			load(file.getAbsolutePath());
		}
	}

	/**
	 * 加载指定字段模板模型
	 * 
	 * @param filePath
	 *            字段模板模型xml配置文件路径
	 * @return
	 * @throws ExceptionHandler
	 */
	public static FieldTemplate load(String filePath) throws ExceptionHandler {
		FieldTemplate fieldTemplate = FieldTemplateParser.parse(filePath);
		if (fieldTemplate != null) {
			container.put(fieldTemplate.getCode(), fieldTemplate);
		}
		return fieldTemplate;
	}

	/**
	 * 从集合中获取字段模板模型对象
	 * 
	 * @param code
	 *            字段模板模型唯一标识符(code)
	 * @return
	 * @throws ExceptionHandler
	 */
	public static FieldTemplate get(String code) throws ExceptionHandler {
		if (code == null || StringUtils.isEmpty(code)) {
			return null;
		}
		return container.get(code);
	}

	/**
	 * 返回所有字段模板模型定义
	 * 
	 * @return
	 */
	public static FieldTemplate[] getAll() {
		FieldTemplate[] fieldTemplates = new FieldTemplate[container.size()];
		@SuppressWarnings({ "unchecked", "rawtypes" })
		List<Table> list = new ArrayList(container.values());
		Collections.sort(list, new ModelSort());
		list.toArray(fieldTemplates);
		list = null;
		return fieldTemplates;
	}

	/**
	 * 返回字段模板模型个数
	 * 
	 * @return
	 */
	public static int size() {
		return container.size();
	}

	/**
	 * 字段模板模型加载完成后的后续处理<br>
	 */
	public static void afterLoad() throws ExceptionHandler {
		FieldTemplateType type = null;
		for (FieldTemplate fieldTemplate : getAll()) {
			/*
			 * 模型检查
			 * 
			 * 有些检查项可以在解析模型时进行验证，但是有些检查项只能在模型全部解析之后进行校验。
			 * 
			 * 例如，BDSelector类型的字段模板中定义了业务对象bizCode，完整的解析过程应该包含bizCode验证。但是业务模型的解析过程中同样对业务字段的字段模板引用进行了校验，如果两边同时校验，则会出现死循环。
			 */

			// 对于BDSelector，bizCode表示的业务对象必须存在
			type = fieldTemplate.getType();
			if (type.equals(FieldTemplateType.BDSELECTOR)) {
				String bizCode = fieldTemplate.getBizCode();
				if (bizCode != null && !StringUtils.isEmpty(bizCode)) {
					if (BizObjectContainer.get(fieldTemplate.getBizCode()) == null) {
						throw new ExceptionHandler(String.format("字段模板 %s[%s] 类型为 %s，引用的业务对象 %s 不存在！", fieldTemplate.getName(), fieldTemplate.getCode(), type, fieldTemplate.getBizCode()));
					}
				}
			}
		}
		type = null;
	}

}
